package com.easylinkin.linkappapi.device.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.NumberUtil;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.config.entity.SysDict;
import com.easylinkin.linkappapi.device.constant.DeviceConstant;
import com.easylinkin.linkappapi.device.constant.DeviceConstant.GrainSize;
import com.easylinkin.linkappapi.device.constant.DeviceConstant.ModelCategoryEnum;
import com.easylinkin.linkappapi.device.dto.EnvironmentalAreaDTO;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.entity.DeviceModel;
import com.easylinkin.linkappapi.device.entity.ElectricyRecords;
import com.easylinkin.linkappapi.device.entity.vo.ElectricyRecordsVo;
import com.easylinkin.linkappapi.device.entity.vo.ElectricyStatisticsVo;
import com.easylinkin.linkappapi.device.mapper.ElectricyRecordsMapper;
import com.easylinkin.linkappapi.device.mapper.EnvironmentalAreaMapper;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.device.service.ElectricyRecordsService;
import com.easylinkin.linkappapi.device.util.DeviceUtil;
import com.easylinkin.linkappapi.openapi.dto.DatapushDTO;
import com.easylinkin.linkappapi.openapi.service.DataPushService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 用电记录 服务实现类
 * </p>
 *
 * @author Xiaoyang
 * @since 2022-08-03
 */
@Service
@Slf4j
public class ElectricyRecordsServiceImpl extends
    ServiceImpl<ElectricyRecordsMapper, ElectricyRecords> implements ElectricyRecordsService {

  @Resource
  private CommonService commonService;
  @Resource
  private LinkappUserContextProducer linkappUserContextProducer;
  @Resource
  private DeviceService deviceService;
  @Resource
  private EnvironmentalAreaMapper environmentalAreaMapper;
  @Resource
  private DataPushService dataPushService;

  @Override
  public boolean saveOne(ElectricyRecords electricyRecords) {
    commonService.setCreateAndModifyInfo(electricyRecords);
    electricyRecords.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    return save(electricyRecords);
  }


  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean updateOne(ElectricyRecords electricyRecords) {
    Assert.notNull(electricyRecords.getId(), "id不能为空");
    commonService.setModifyInfo(electricyRecords);
    electricyRecords.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    return updateById(electricyRecords);
  }

  @Override
  public IPage<ElectricyRecords> selectPage(Page page, ElectricyRecordsVo electricyRecords) {
    electricyRecords.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    return baseMapper.selectPage(page, electricyRecords);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean deleteByIds(List<Long> idList) {
    return removeByIds(idList);
  }

  @Override
  public void export(ElectricyRecordsVo electricyRecords, HttpServletRequest request, HttpServletResponse
      response) {

    IPage<ElectricyRecords> page = selectPage(new Page(0, -1), electricyRecords);
    List<ElectricyRecords> records = page.getRecords();

    String keyValue = "设备号:deviceCode,用水增量:waterIncrement,累计用水:waterTotal,止码读数:stopReading,采集时间:collectTime";
    String title = "ElectricyRecords导出数据";
    String fileName = title + ".xls";
    try {
      OutputStream outputStream = OutputStreamUtil
          .getOutputStream(request, response, fileName);
      ExcelTools.exportExcel(outputStream, keyValue, records, ExcelConstant.XLS, title);
      response.flushBuffer();
      outputStream.close();
    } catch (IOException e) {
      log.error("excel导出失败", e);
      throw new RuntimeException("excel导出失败！IOException异常" + e.getMessage());
    } catch (Exception e) {
      log.error("excel导出失败", e);
      throw new RuntimeException("excel导出失败！" + e.getMessage());
    }
  }

  @Override
  public ElectricyRecords getOneById(Serializable id) {
    return baseMapper.getOneById(id);
  }

  @Override
  public void datapushHandler(DatapushDTO datapushDTO) {
    // 流水处理流程
    JSONObject data = datapushDTO.getData();
    String deviceCode = datapushDTO.getDevice_id();
//      Device device = new Device();
//      device.setCode(deviceCode);
//      List<Device> deviceList = deviceService.selectDevices(device);
//      if (deviceList == null || deviceList.size() <= 0) {
//        return ;
//      }
//      device = deviceList.get(0);
    //将查询逻辑放入主线程
    Device device = datapushDTO.getDevice_data_latest();
    if (!DeviceConstant.RailwayDeviceType.ELECTRIC_METER.getDescription().contains(device.getDeviceUnit().getDeviceTypeName())) {
      return;
    }
    // 当前累计流量
    Double combinedActiveEnergy = data.getDouble("combined_active_energy");

    Double  a_phase_voltage = data.getDouble("a_phase_voltage");
    Double b_phase_voltage  = data.getDouble("b_phase_voltage");
    Double c_phase_voltage  = data.getDouble("c_phase_voltage");
    Double  a_phase_current = data.getDouble("a_phase_current");
    Double  b_phase_current = data.getDouble("b_phase_current");
    Double c_phase_current = data.getDouble("c_phase_current");
    Double  active_power = data.getDouble("active_power");
    if(null == combinedActiveEnergy){
      return;
    }
//      combinedActiveEnergy = NumberUtil.div(combinedActiveEnergy,1000d,2);
    ElectricyRecords electricyRecords = new ElectricyRecords();
    electricyRecords.setDeviceCode(deviceCode);
    electricyRecords.setTenantId(device.getTenantId());
    //扩展区域id
    DeviceModel deviceModel = dataPushService.getDeviceModel(deviceCode);
    if (deviceModel!=null && deviceModel.getEnvironmentalAreaId()!=null){
      electricyRecords.setAreaId(deviceModel.getEnvironmentalAreaId());
    }
    electricyRecords.setCollectTime(new Date());
    electricyRecords.setCreateTime(new Date());
    electricyRecords.setStopReading(combinedActiveEnergy);
    // 设备用水列表 倒序
    ElectricyRecordsVo electricyRecordsVo = new ElectricyRecordsVo();
    electricyRecordsVo.setDeviceCode(deviceCode);
    electricyRecordsVo.setTenantId(device.getTenantId());
    List<ElectricyRecords> list = baseMapper.findByDeviceCode(electricyRecordsVo);
    if(CollectionUtil.isEmpty(list)){
      // 第一条流水记录 增量为combinedActiveEnergy
      electricyRecords.setElectricyIncrement(0d);
      electricyRecords.setElectricyTotal(0d);
    }else{
      ElectricyRecords endFlow = list.get(0);// 最新一条 计算增量
      Double electricyIncrement = 0d;
      if(combinedActiveEnergy.compareTo(endFlow.getStopReading()) == 1){
        electricyIncrement = NumberUtil.sub(combinedActiveEnergy,endFlow.getStopReading(),2);
      }
      electricyRecords.setElectricyIncrement(electricyIncrement);
      electricyRecords.setElectricyTotal(NumberUtil.add(endFlow.getElectricyTotal(),electricyIncrement,2));
    }
    electricyRecords.setAPhaseCurrent(a_phase_current);
    electricyRecords.setAPhaseVoltage(a_phase_voltage);
    electricyRecords.setBPhaseCurrent(b_phase_current);
    electricyRecords.setBPhaseVoltage(b_phase_voltage);
    electricyRecords.setCPhaseCurrent(c_phase_current);
    electricyRecords.setCPhaseVoltage(c_phase_voltage);
    electricyRecords.setActivePower(active_power);
    baseMapper.insert(electricyRecords);
  }

  @Override
  public ElectricyStatisticsVo getElectricyStatistics(ElectricyRecordsVo electricyRecordsVo) {
    String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
    ElectricyStatisticsVo electricyStatisticsVo = new ElectricyStatisticsVo();
    electricyStatisticsVo.setTodayElectricy(0d);
    electricyStatisticsVo.setWeekElectricy(0d);
    electricyStatisticsVo.setMonthElectricy(0d);
    electricyStatisticsVo.setTodayElectricy(0d);
    // 获取喷淋统计数据
    electricyRecordsVo.setTenantId(tenantId);
    // 设备用电列表 倒序
    if(StringUtils.isBlank(electricyRecordsVo.getDeviceCode())){
      // 查询所有一级区域设备
      EnvironmentalAreaDTO areaDTO = new EnvironmentalAreaDTO();
      areaDTO.setLevel(1); // 一级区域
      areaDTO.setParentId(0); // 父节点id
      areaDTO.setType(2); // 用电
      areaDTO.setTenantId(tenantId);
      List<EnvironmentalAreaDTO> deviceModels = environmentalAreaMapper.selectDeviceByArea(areaDTO);
      if(CollectionUtil.isNotEmpty(deviceModels)){
        List<String> deviceCodes = deviceModels.stream()
            .map(EnvironmentalAreaDTO::getDeviceCode).collect(Collectors.toList());
        electricyRecordsVo.setDeviceCodes(deviceCodes);
      }
    }
    if(StringUtils.isNotEmpty(electricyRecordsVo.getDeviceCode())||CollectionUtil.isNotEmpty(electricyRecordsVo.getDeviceCodes())){
      // 累计用电量
      Double totalElectricy = baseMapper.getSumElectricyByTime(electricyRecordsVo);
      if(null != totalElectricy){
        electricyStatisticsVo.setTotalElectricy(totalElectricy);
      }
      // 今日用电量
      electricyRecordsVo.setStartTime(DateUtil.getCurrentDayMixDate());
      electricyRecordsVo.setEndTime(DateUtil.getCurrentDayMaxDate());
      Double todayElectricy = baseMapper.getSumElectricyByTime(electricyRecordsVo);
      if(null != todayElectricy){
        electricyStatisticsVo.setTodayElectricy(todayElectricy);
      }
      // 本周用电量
      electricyRecordsVo.setStartTime(DateUtil.getCurrentDayMixDate(DateUtil.getNowWeekMonday(new Date())));
      electricyRecordsVo.setEndTime(DateUtil.getCurrentDayMaxDate(new Date()));
      Double weekElectricy = baseMapper.getSumElectricyByTime(electricyRecordsVo);
      if(null != weekElectricy){
        electricyStatisticsVo.setWeekElectricy(weekElectricy);
      }
      // 本月用电量
      electricyRecordsVo.setStartTime(DateUtil.getCurrentDayMixDate(DateUtil.getNowMonthFirstDay(new Date())));
      electricyRecordsVo.setEndTime(DateUtil.getCurrentDayMaxDate(new Date()));
      Double monthElectricy = baseMapper.getSumElectricyByTime(electricyRecordsVo);
      if(null != monthElectricy){
        electricyStatisticsVo.setMonthElectricy(monthElectricy);
      }
      //获取最新的记录
      ElectricyRecords electricyRecords = baseMapper.getLatestRecord(electricyRecordsVo);
      if(electricyRecords!=null){
        electricyStatisticsVo.setCollectTime(electricyRecords.getCollectTime());
      }
    }
    return electricyStatisticsVo;
  }

  @Override
  public List<ElectricyStatisticsVo> getElectricyStatisticsList(ElectricyRecordsVo electricyRecordsVo) {
    electricyRecordsVo.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    List<Date> dates = DateUtil
        .checkDateIsLegal(electricyRecordsVo.getGrainSize(),
            DateUtil.format(electricyRecordsVo.getStartTime(),DateUtil.DATE_TIME_FORMAT_DEFAULT),
            DateUtil.format(electricyRecordsVo.getEndTime(),DateUtil.DATE_TIME_FORMAT_DEFAULT));

    if(CollectionUtil.isEmpty(dates)){
      return null;
    }

    if(GrainSize.DAY.equals(electricyRecordsVo.getGrainSize())){
      return getDayData(dates,electricyRecordsVo);
    }
    if(GrainSize.WEEK.equals(electricyRecordsVo.getGrainSize())){
      return getWeekData(dates,electricyRecordsVo);
    }
    if(GrainSize.MONTH.equals(electricyRecordsVo.getGrainSize())){
      return getMonthData(dates,electricyRecordsVo);
    }

    return null;
  }



  private List<ElectricyStatisticsVo> getDayData(List<Date> days, ElectricyRecordsVo electricyRecordsVo) {
    Date startTime = days.get(0);
    Date endTime = days.get(days.size() - 1);
    electricyRecordsVo.setStartTime(startTime);
    electricyRecordsVo.setEndTime(endTime);
    // 初始化
    List<ElectricyStatisticsVo> dayList = new ArrayList<>(days.size());
    FastDateFormat format = FastDateFormat.getInstance("yyyyMMdd");
    // 查询统计
    List<ElectricyStatisticsVo> result = baseMapper.getElectricyStatisticsVoByDay(electricyRecordsVo);
    // 初始化数据
    Map<String,ElectricyStatisticsVo> resultMap = result.stream().collect(Collectors
        .toMap(ElectricyStatisticsVo::getDays, Function
            .identity(), (k1, k2) -> k1));
    for(Date date : days){
      String day = format.format(date);
      ElectricyStatisticsVo vo = null;
      if(null != resultMap && resultMap.containsKey(day)){
        vo = resultMap.get(day);
      }else{
        vo = new ElectricyStatisticsVo();
        vo.setDays(day);
        vo.setTodayElectricy(0.0d);
      }
      dayList.add(vo);
    }
    if(CollectionUtil.isEmpty(dayList)){
      return null;
    }
    for(ElectricyStatisticsVo p:dayList){
      Date day = DateUtil.parse(p.getDays(),"yyyyMMdd");
      String refDate = DateUtil.format(day,DateUtil.DATE_TIME_FORMAT_DAY);
      p.setRefDate(refDate);
    }
    return dayList;
  }

  private List<ElectricyStatisticsVo> getWeekData(List<Date> weekEndDays, ElectricyRecordsVo electricyRecordsVo) {
    Date startTime = DateUtil.findMondayBySunDay(weekEndDays.get(0));
    Date endTime = weekEndDays.get(weekEndDays.size() - 1);
    electricyRecordsVo.setStartTime(startTime);
    electricyRecordsVo.setEndTime(endTime);
    // 初始化
    List<ElectricyStatisticsVo> weekList = new ArrayList<>(weekEndDays.size());
    // 查询统计
    List<ElectricyStatisticsVo> result = baseMapper.getElectricyStatisticsVoByDay(electricyRecordsVo);
    // 初始化数据
    Map<String,ElectricyStatisticsVo> resultMap = result.stream().collect(Collectors.toMap(ElectricyStatisticsVo::getWeeks, Function
        .identity(), (k1, k2) -> k1));
    for(Date date : weekEndDays){
      String week = null;
      try {
        week = DateUtil.getWeekOfYear(date);
      } catch (Exception e) {
        e.printStackTrace();
      }
      ElectricyStatisticsVo vo = null;
      if(null != resultMap && resultMap.containsKey(week)){
        vo = resultMap.get(week);
      }else{
        vo = new ElectricyStatisticsVo();
        vo.setWeeks(week);
        vo.setWeekElectricy(0.0d);
      }
      weekList.add(vo);
    }
    if(CollectionUtil.isEmpty(weekList)){
      return null;
    }
    for(ElectricyStatisticsVo p:weekList){
      String refDate = p.getWeeks();
      refDate = DateUtil.getTimeIntervalByWeek(refDate);
      p.setRefDate(refDate);
    }
    return weekList;

  }

  private List<ElectricyStatisticsVo> getMonthData(List<Date> monthEndDays, ElectricyRecordsVo electricyRecordsVo) {
    Date startTime = DateUtil.findFirstDayOfMonth(monthEndDays.get(0));
    Date endTime = monthEndDays.get(monthEndDays.size() - 1);
    electricyRecordsVo.setStartTime(startTime);
    electricyRecordsVo.setEndTime(endTime);
    // 初始化
    List<ElectricyStatisticsVo> monthList = new ArrayList<>(monthEndDays.size());
    FastDateFormat format = FastDateFormat.getInstance("yyyyMM");
    // 查询统计
    List<ElectricyStatisticsVo> result = baseMapper.getElectricyStatisticsVoByDay(electricyRecordsVo);
    // 初始化数据
    Map<String,ElectricyStatisticsVo> resultMap = result.stream().collect(Collectors
        .toMap(ElectricyStatisticsVo::getMonths, Function
            .identity(), (k1, k2) -> k1));
    for(Date date : monthEndDays){
      String month = format.format(date);
      ElectricyStatisticsVo vo = null;
      if(null != resultMap && resultMap.containsKey(month)){
        vo = resultMap.get(month);
      }else{
        vo = new ElectricyStatisticsVo();
        vo.setMonths(month);
        vo.setMonthElectricy(0.0d);
      }
      monthList.add(vo);
    }
    if(CollectionUtil.isEmpty(monthList)){
      return null;
    }
    for(ElectricyStatisticsVo p:monthList){
      String refDate = p.getMonths();
      refDate = DateUtil.getTimeIntervalByMonth(refDate);
      p.setRefDate(refDate);
    }
    return monthList;
  }

  @Override
  public List<Map<String, Object>> electricyByYear(ElectricyRecordsVo electricyRecordsVo) {
    List<Map<String,Object>> result = null;
    if (String.valueOf(Year.now().getValue()).equals(electricyRecordsVo.getYear())){
         //输入的当前年份
         result = DateUtil.monthAndEncapsulationOldYear(electricyRecordsVo.getYear());
    }else{
         //输入的非当前年份
         result = DateUtil.monthAndEncapsulationOldYear(electricyRecordsVo.getYear());
    }
    String startTime =  Objects.toString(result.get(0).get("nianYue"),"");
    Map<String, Object> headMap = new HashMap<>();
    headMap.put("nianYue",DateUtil.upYearAndMonth(startTime));
    result.add(0,headMap);
    //获取租户id 查询需要统计的数据
    String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
    electricyRecordsVo.setTenantId(tenantId);
    electricyRecordsVo.setStartTimeStr(Objects.toString(result.get(0).get("nianYue"),"")+"-01");
    electricyRecordsVo.setEndTimeStr(DateUtil.getLastDate(Objects.toString(result.get(result.size()-1).get("nianYue"),"")));
    //List<ElectricyRecords> electricyRecords = baseMapper.selectByList(electricyRecordsVo);
    List<ElectricyRecords> electricyRecords = baseMapper.selectListByYears(electricyRecordsVo);
    //遍历
    List<ElectricyRecords> transferStation = new ArrayList<>();
    boolean zero = false;
    Double upSum = 0.0;
    for(Map<String,Object> maps:result){
        Double sum = 0.0;
        String nianYue = Objects.toString(maps.get("nianYue"), "");
      String plaintext = YearMonth.parse(nianYue, DateTimeFormatter.ofPattern("yyyy-MM"))
              .format(DateTimeFormatter.ofPattern("yyyy年M月"));
      maps.put("plaintext",plaintext);
        if (zero) {
          maps.put("sum", sum);
          maps.put("unit", "kwh");
          maps.put("change", "0.00%");

          continue;
        }
        if (transferStation.size() == 0 ){
          int leftIndex = 0;
          int rightIndex  = electricyRecords.size()-1;
          while (leftIndex<=rightIndex){
              if (leftIndex == rightIndex){
                ElectricyRecords leftRecords = electricyRecords.get(leftIndex);
                String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
                if (leftCollectTime.startsWith(nianYue)){
                  sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
                }else{
                  transferStation.add(leftRecords);
                }
                break;
              }
            ElectricyRecords leftRecords = electricyRecords.get(leftIndex);
            String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
            if (leftCollectTime.startsWith(nianYue)){
              sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
            }else{
              transferStation.add(leftRecords);
            }
            leftIndex++;
            ElectricyRecords rightRecords = electricyRecords.get(rightIndex);
            String rightCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(rightRecords.getCollectTime());
            if (rightCollectTime.startsWith(nianYue)){
              sum = (Objects.isNull(rightRecords.getElectricyIncrement())?0.0:rightRecords.getElectricyIncrement())+sum;
            }else{
              transferStation.add(rightRecords);
            }
            rightIndex--;
          }
        }else{
          List<ElectricyRecords> letw = transferStation;
          transferStation = new ArrayList<>();
          int leftIndex = 0;
          int rightIndex  = letw.size()-1;
          while (leftIndex<=rightIndex){
            if (leftIndex == rightIndex){
              ElectricyRecords leftRecords = letw.get(leftIndex);
              String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
              if (leftCollectTime.startsWith(nianYue)){
                sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
              }else{
                transferStation.add(leftRecords);
              }
              break;
            }
            ElectricyRecords leftRecords = letw.get(leftIndex);
            String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
            if (leftCollectTime.startsWith(nianYue)){
              sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;

            }else{
              transferStation.add(leftRecords);
            }
            leftIndex++;
            ElectricyRecords rightRecords = letw.get(rightIndex);
            String rightCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(rightRecords.getCollectTime());
            if (rightCollectTime.startsWith(nianYue)){
              sum = (Objects.isNull(rightRecords.getElectricyIncrement())?0.0:rightRecords.getElectricyIncrement())+sum;
            }else{
              transferStation.add(rightRecords);
            }
            rightIndex--;
          }
        }
      if (transferStation.size() == 0) {
        zero = true;
      }

      maps.put("change",calculateGrowthRate(sum,upSum));
      upSum = sum;
      //保留两位小数
      BigDecimal bd = new BigDecimal(Double.toString(sum));
      bd = bd.setScale(2, RoundingMode.HALF_UP);
      maps.put("sum", bd.doubleValue());
      maps.put("unit", "kwh");

    }
    result.remove(0);
    return sortByField(electricyRecordsVo.getSortField(),electricyRecordsVo.getSortMethod(),result);
  }

  @Override
  public Map<String, Object> electricyByDayAndHour(ElectricyRecordsVo electricyRecordsVo) {
    String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
    Map<String, Object> result = new HashMap<>();
    //初始化
    result.put("unit","kwh");
    List<String> abscissa = new ArrayList<>();
    result.put("abscissa",abscissa);
    List<Double> coordinate = new ArrayList<>();
    result.put("coordinate",coordinate);
    List<String> last24HoursRange = null;
    List<ElectricyRecords> electricyRecords = null;
    List<ElectricyRecords> transferStation = new ArrayList<>();
    boolean zero = false;
     switch (electricyRecordsVo.getDailyOrMonthly()){
            case 0:
        //逐日
        last24HoursRange = DateUtil.getLast24HoursRange(electricyRecordsVo.getDailyOrMonthlyDate());
        electricyRecordsVo.setTenantId(tenantId);
        electricyRecordsVo.setStartTimeStrH(last24HoursRange.get(0));
        electricyRecordsVo.setEndTimeStrH(last24HoursRange.get(last24HoursRange.size()-1));
        electricyRecords = baseMapper.selectByList(electricyRecordsVo);
        break;
      case 1:
          //逐日
        if (DateUtil.getNowMonthAndDay().equals(electricyRecordsVo.getDailyOrMonthlyDate())){
          last24HoursRange = DateUtil.getLast30Days();
        }else{
          last24HoursRange = DateUtil.getAllLocalDatesOfMonth(electricyRecordsVo.getDailyOrMonthlyDate());
        }

        electricyRecordsVo.setTenantId(tenantId);
        electricyRecordsVo.setStartTimeStr(last24HoursRange.get(0));
        electricyRecordsVo.setEndTimeStr(last24HoursRange.get(last24HoursRange.size()-1));
        electricyRecords = baseMapper.selectByList(electricyRecordsVo);
        break;

      default:break;
    }
    //遍历
    for (String hours:last24HoursRange){
      abscissa.add(hours);
      //逐时统计
      Double sum = 0.00;
      if (zero) {
        coordinate.add(sum);
        continue;
      }
      if (transferStation.size() == 0 ){
        int leftIndex = 0;
        int rightIndex  = electricyRecords.size()-1;
        while (leftIndex<=rightIndex){
          if (leftIndex == rightIndex){
            ElectricyRecords leftRecords = electricyRecords.get(leftIndex);
            String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
            if (leftCollectTime.startsWith(hours)){
              sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
            }else{
              transferStation.add(leftRecords);
            }
            break;
          }
          ElectricyRecords leftRecords = electricyRecords.get(leftIndex);
          String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
          if (leftCollectTime.startsWith(hours)){
            sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
          }else{
            transferStation.add(leftRecords);
          }
          leftIndex++;
          ElectricyRecords rightRecords = electricyRecords.get(rightIndex);
          String rightCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(rightRecords.getCollectTime());
          if (rightCollectTime.startsWith(hours)){
            sum = (Objects.isNull(rightRecords.getElectricyIncrement())?0.0:rightRecords.getElectricyIncrement())+sum;
          }else{
            transferStation.add(rightRecords);
          }
          rightIndex--;
        }
      }else{
        List<ElectricyRecords> letw = transferStation;
        transferStation = new ArrayList<>();
        int leftIndex = 0;
        int rightIndex  = letw.size()-1;
        while (leftIndex<=rightIndex){
          if (leftIndex == rightIndex){
            ElectricyRecords leftRecords = letw.get(leftIndex);
            String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
            if (leftCollectTime.startsWith(hours)){
              sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;
            }else{
              transferStation.add(leftRecords);
            }
            break;
          }
          ElectricyRecords leftRecords = letw.get(leftIndex);
          String leftCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(leftRecords.getCollectTime());
          if (leftCollectTime.startsWith(hours)){
            sum = (Objects.isNull(leftRecords.getElectricyIncrement())?0.0:leftRecords.getElectricyIncrement())+sum;

          }else{
            transferStation.add(leftRecords);
          }
          leftIndex++;
          ElectricyRecords rightRecords = letw.get(rightIndex);
          String rightCollectTime = DateUtil.getYYYYMMDDHHMMSSDate(rightRecords.getCollectTime());
          if (rightCollectTime.startsWith(hours)){
            sum = (Objects.isNull(rightRecords.getElectricyIncrement())?0.0:rightRecords.getElectricyIncrement())+sum;
          }else{
            transferStation.add(rightRecords);
          }
          rightIndex--;

        }
      }
      if (transferStation.size() == 0) {
        zero = true;
      }
      BigDecimal bd = new BigDecimal(Double.toString(sum));
      bd = bd.setScale(2, RoundingMode.HALF_UP);
      coordinate.add(bd.doubleValue());
    }
    result.put("unit","kwh");
    result.put("abscissa",abscissa);
    result.put("coordinate",coordinate);
    return result;
  }

  @Override
  public List<ElectricyRecords> codeByNewRecords(String tenantId, List<String> codes) {
    return baseMapper.codeByNewRecords(tenantId,codes);
  }


  @Override
  public ElectricyRecords getStartRecord() {
    ElectricyRecordsVo electricyRecordsVo = new ElectricyRecordsVo();
    electricyRecordsVo.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    return baseMapper.getEarlyRecord(electricyRecordsVo);
  }

  public List<Map<String,Object>>  sortByField(String sortField, Integer sortMethod, List<Map<String,Object>> dates){
    // 创建新列表避免修改原始数据
    List<Map<String,Object>> sortedList = new ArrayList<>(dates);
    Comparator<Map<String,Object>> comparator = null;
    if ("year".equals(sortField)){
      comparator = Integer.valueOf(0).equals(sortMethod) ? DESC_COMPARATOR_YEAR :ASC_COMPARATOR_YEAR;
    }else if ("sum".equals(sortField)){
      comparator = Integer.valueOf(0).equals(sortMethod) ? DESC_COMPARATOR_SUM : ASC_COMPARATOR_SUM;
    }
    if (comparator == null){
      return sortedList;
    }
    sortedList.sort(comparator);
    return sortedList;
  }

  /**
   * 自定义比较器：按耗电量升序排序
   */
  private static final Comparator<Map<String,Object>> ASC_COMPARATOR_SUM = (s1, s2) -> {
    try {
      Double ym1 = Double.valueOf(Objects.toString(s1.get("sum")));
      Double ym2 = Double.valueOf(Objects.toString(s2.get("sum")));
      return ym1.compareTo(ym2);
    } catch (DateTimeParseException e) {
      return 0; // 无效数据保持原位置
    }
  };
  /**
   * 自定义比较器：按耗电量降序序排序
   */
  private static final Comparator<Map<String,Object>> DESC_COMPARATOR_SUM  = (s1, s2) -> {
    try {
      Double ym1 = Double.valueOf(Objects.toString(s1.get("sum")));
      Double ym2 = Double.valueOf(Objects.toString(s2.get("sum")));
      return ym2.compareTo(ym1);
    } catch (DateTimeParseException e) {
      return 0;
    }
  };
  /**
   * 自定义比较器：按年月升序排序
   */
  private static final Comparator<Map<String,Object>> ASC_COMPARATOR_YEAR = (s1, s2) -> {
    try {
      YearMonth ym1 = parseYearMonth(Objects.toString(s1.get("plaintext")));
      YearMonth ym2 = parseYearMonth(Objects.toString(s2.get("plaintext")));
      return ym1.compareTo(ym2);
    } catch (DateTimeParseException e) {
      return 0;
    }
  };

  /**
   * 自定义比较器：按年月降序排序
   */
  private static final Comparator<Map<String,Object>> DESC_COMPARATOR_YEAR  = (s1, s2) -> {
    try {
      YearMonth ym1 = parseYearMonth(Objects.toString(s1.get("plaintext")));
      YearMonth ym2 = parseYearMonth(Objects.toString(s2.get("plaintext")));
      return ym2.compareTo(ym1);
    } catch (DateTimeParseException e) {
      return 0;
    }
  };
  // 解析 "yyyy年M月" 格式为 YearMonth 对象
  private static YearMonth parseYearMonth(String dateStr) {
    // 创建支持中文的格式化器
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月");
    return YearMonth.parse(dateStr, formatter);
  }

  /**
   * 计算同比增长百分比（基础方法）
   *
   * @param currentValue 本期数值
   * @param previousValue 同期数值（上年同期）
   * @return 同比增长百分比字符串（保留两位小数）
   */
  public static String calculateGrowthRate(double currentValue, double previousValue) {
    if (previousValue == 0) {
      if (currentValue>0){
        return "+100.00%";
      }
      // 处理分母为零的情况
      return currentValue == 0 ? "0.00%" : "无限增长";
    }
    // 计算增长率
    double growthRate = (currentValue - previousValue) / previousValue * 100;

    // 格式化输出
    if (growthRate<0){
      return String.format("%.2f%%", growthRate);
    }else{
      return "+"+String.format("%.2f%%", growthRate);
    }
  }




}
